package org.apache.commons.dbutils2;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;


public class BatchInsertExecutor extends BatchExecutor {

    /**
     * Constructs a BatchInsertExecutor given a connection and SQL statement.
     * 
     * @param conn The connection to use during execution.
     * @param sql The SQL statement.
     * @param closeConnection If the connection should be closed or not.
     * @throws SQLException thrown if there is an error during execution.
     */
    BatchInsertExecutor(final Connection conn, final String sql, final boolean closeConnection) throws SQLException {
        super(conn, sql, closeConnection);
    }

    /**
     * Calls batch after checking the parameters to ensure nothing is null.
     * 
     * @return the result generated by the handler.
     * @throws SQLException If there are database or parameter errors.
     * @see org.apache.commons.dbutils2.UpdateExecutor#execute()
     */
    public <T> T execute(final ResultSetHandler<T> handler) throws SQLException {
        // throw an exception if there are unmapped parameters
        this.throwIfUnmappedParams();

        // make sure our handler is not null
        if (handler == null) {
            if (getCloseConn()) {
                close(getConnection());
            }
            throw new SQLException("Null ResultSetHandler");
        }

        ResultSet resultSet = null;
        
        try {
            // execute the query and get the keys, wrapping them
            getStatement().executeBatch();
            resultSet = this.wrap(getStatement().getGeneratedKeys());
            
            // execute the handler
            return handler.handle(resultSet);
        } catch (SQLException e) {
            rethrow(e);
        } finally {
            try {
                close(resultSet);
            } finally {
                close(getStatement());
                if (getCloseConn()) {
                    close(getConnection());
                }
            }
        }

        // we get here only if something is thrown
        return null;
    }

}
